package com.xuetang9.service.a.impl;

import com.github.pagehelper.PageHelper;
import com.xuetang9.dao.*;
import com.xuetang9.domain.*;
import com.xuetang9.dto.InputDto;
import com.xuetang9.dto.a.ListRequestDTO;
import com.xuetang9.dto.a.ModifyDefectLevelDTO;
import com.xuetang9.service.DefectService;
import com.xuetang9.utils.DateUtil;
import com.xuetang9.vo.ListVO;
import com.xuetang9.vo.a.ConfirmDefectVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @工能 处理缺陷等级确认任务
 * @作者 杜目杰
 * @时间 2020/5/18
 * @地点 公司
 * @版本 1.0.0
 * @版权 老九学堂
 */
@Service("DefectServiceImplA")
public class DefectServiceImpl implements DefectService {
    // poleDefect表的操作对象
    @Autowired
    PoleDefectMapper poleDefectMapper;
    //task表的操作对象
    @Autowired
    TaskMapper taskMapper;
    //pole表的操作对象
    @Autowired
    PoleMapper poleMapper;
    //巡检任务回执表
    @Autowired
    RecepitInspMapper recepitInspMapper;
    //缺陷列表
    @Autowired
    DefectMapper defectMapper;

    /**
     * 执行缺陷等级确认业务
     *
     * @param inputDto 业务处理输入对象
     * @return 处理结果
     */
    @Override
    public int confirmDefectLevel(InputDto inputDto) {
        int result = -1;
        // 得到要处理的业务名称
        String in = inputDto.function;
        //选中对应的功能处理业务
        switch (in) {
            case "修改缺陷等级":
                result = updateDefectLevel(inputDto);
        }
        return result;
    }

    /**
     * 处理缺陷管理的查询类业务
     *
     * @param inputDto 业务处理输入对象
     * @return 前端显示对象
     */
    @Override
    public ListVO defectLevelView(InputDto inputDto) {
        // 保存前端显示数据
        ListVO listVO = new ListVO();
        // 得到要处理的业务名称
        String in = inputDto.function;
        //选中对应的功能处理业务
        switch (in) {
            case "查询缺陷等级列表":
                listVO = selectDefectLevel(inputDto);
        }
        return listVO;
    }

    /**
     * 处理缺陷记录列表查询
     *
     * @param inputDto 业务处理输入对象
     * @return 前端显示对象
     */
    private ListVO selectDefectLevel(InputDto<ListRequestDTO<ConfirmDefectVO>> inputDto) {
        // 提取属于PoleDefect表的查询条件进行查询并得到查询结果
        List<PoleDefect> poleDefects = getAllIPending(inputDto.date);
        // 进行二次赛选，并得到最终结果
        List<ConfirmDefectVO> confirmDefectVOS = listPoleDefectTwoSelect(poleDefects, inputDto.date.request);

        // 分页
        int times = 0;
        int page = inputDto.date.page;
        int pageSize = inputDto.date.pageSize;
        List<ConfirmDefectVO> request = new ArrayList<>();
        for (ConfirmDefectVO t : confirmDefectVOS
        ) {
            times++;
            if (times > (page - 1) * pageSize && times <= page * pageSize) {
                request.add(t);
            }
        }
        // 配置显示集合
        ListVO listVO = new ListVO();
        listVO.setResult(confirmDefectVOS);
        listVO.setTotal(times);
        return listVO;
    }

    /**
     * 通过条件赛选传入的poleDefect集合
     *
     * @param poleDefects     poleDefect集合
     * @param confirmDefectVO 条件
     * @return 显示数据
     */
    private List<ConfirmDefectVO> listPoleDefectTwoSelect(List<PoleDefect> poleDefects, ConfirmDefectVO confirmDefectVO) {
        //保存符合条件集合
        List<ConfirmDefectVO> resultList = new ArrayList<>();
        // 将poleDefects集合转为ConfirmDefectVO集合
        List<ConfirmDefectVO> confirmDefectVOS = poleDefectsToConfirmDefectVOs(poleDefects);
        // 剔除不符合条件的查询结果
        for (int i = 0; i < confirmDefectVOS.size(); i++) {
            // 根据条件得到匹配结果
            boolean result = comareConfirmDefectVOByTaskIdWayIdDefectType(confirmDefectVOS.get(i), confirmDefectVO);
            // 如果结果为false就从结果中移除
            if (result) {
                resultList.add(confirmDefectVOS.get(i));
            }
        }
        return resultList;
    }

    /**
     * 得到符合查询条件的结果
     *
     * @param confirmDefectVO  被比较的对象
     * @param confirmDefectVO1 赛选条件
     * @return 符合条件的查询集合
     */
    private boolean comareConfirmDefectVOByTaskIdWayIdDefectType(ConfirmDefectVO confirmDefectVO, ConfirmDefectVO confirmDefectVO1) {
        // 赛选结果
        boolean result = true;
        // 根据任务编号赛选
        if (confirmDefectVO1.getTask_id() != null && !confirmDefectVO1.getTask_id().equals(confirmDefectVO.getTask_id())) {
            result = false;
        }
        // 根据线路编号赛选
        if (confirmDefectVO1.getCircuit_id() != null && !confirmDefectVO1.getCircuit_id().equals(confirmDefectVO.getCircuit_id())) {
            result = false;
        }
        // 根据缺陷类型赛选
        if (confirmDefectVO1.getDefect_type() != null && !confirmDefectVO1.getDefect_type().equals(confirmDefectVO.getDefect_type())) {
            result = false;
        }
        return result;
    }


    /**
     * 根据业务执行缺陷等级修改
     *
     * @param inputDto 前端传入数据
     * @return 更新处理结果
     */
    private int updateDefectLevel(InputDto<ModifyDefectLevelDTO> inputDto) {
        // 组装poleDefect表的数据
        PoleDefect poleDefect = setPoleDefectByModifyDefectLevelDTO(inputDto.date);
        // 根据得到的组装数据更新缺陷表
        int updateResult = updatePoleDefect(poleDefect);
        return updateResult;
    }

    /**
     * 根据poleDefect更新数据
     *
     * @param poleDefect 杆塔缺陷记录表
     * @return 修改结果
     */
    private int updatePoleDefect(PoleDefect poleDefect) {
        System.out.println(poleDefect);
        return poleDefectMapper.updatePoleDefect(poleDefect);
    }

    /**
     * 将date中属于PoleDefect中的数据提取出来
     *
     * @param date ConfirmDefectVO缺陷等级页面显示和传入对象
     * @return PoleDefect的实例化对象
     */
    private PoleDefect setPoleDefectByModifyDefectLevelDTO(ModifyDefectLevelDTO date) {
        PoleDefect poleDefect = new PoleDefect();
        poleDefect.setId(date.getId());
        poleDefect.setPoleDefectLevel(date.getGrade());
        return poleDefect;
    }

    /**
     * 将所有poleDefect转换为ConfirmDefectVO
     *
     * @param poleDefects 要转换的poleDefect集合
     * @return 转换后的集合
     */
    private List<ConfirmDefectVO> poleDefectsToConfirmDefectVOs(List<PoleDefect> poleDefects) {
        List<ConfirmDefectVO> confirmDefectVOS = new ArrayList<>();
        // 将poleDefects全部转换为ConfirmDefectVO
        if (poleDefects.size() > 0) {
            for (PoleDefect p : poleDefects
            ) {
                confirmDefectVOS.add(poleDefectToConfirmDefectVO(p));
            }
        }
        return confirmDefectVOS;
    }

    /**
     * 得到ConfirmDefectVO
     *
     * @param poleDefect
     * @return
     */
    private ConfirmDefectVO poleDefectToConfirmDefectVO(PoleDefect poleDefect) {
        ConfirmDefectVO con = new ConfirmDefectVO();
        // 得到任务编号
        String taskId = getTaskIdByPoleDefectId(poleDefect.getId());
        // 得到线路编号
        String wayId = getWayIdByPoleId(poleDefect.getPoleId());
        // 得到错误类型
        String defectType = getDefectTypeByDefectId(poleDefect.getDefectId());
        con.setId(poleDefect.getId());

        con.setTask_id(taskId);
        con.setCircuit_id(wayId);
        con.setTower_id(poleDefect.getPoleId());
        con.setDefect_type(defectType);
        con.setDefect_level(poleDefect.getPoleDefectLevel());
        con.setServiceability_rate(poleDefect.getIntactRate() + "");
        con.setDescription("无");
        con.setDiscovery(DateUtil.changeStyle(poleDefect.getCreateTime()));
        con.setPeople_Finder(poleDefect.getFinder());
        return con;
    }

    /**
     * 得到错误类型
     *
     * @param defectId
     * @return
     */
    private String getDefectTypeByDefectId(Integer defectId) {
        Defect defect = defectMapper.selectById(defectId);
        if (defect != null) {
            return defect.getDefectName();
        }
        return null;
    }

    /**
     * 通过杆塔id得到线路编号
     *
     * @param poleId 杆塔id
     * @return 线路编码
     */
    private String getWayIdByPoleId(String poleId) {
        // 根据poleId得到po整条数据，在得到编号
        Pole pole = selectPole(poleId);
        if (pole != null) {
            return pole.getPoleAddress();
        }
        return null;
    }

    /**
     * 通过PoleDefectId得到任务编码
     *
     * @param poleDefectId
     * @return
     */
    private String getTaskIdByPoleDefectId(int poleDefectId) {
        // 通过poleDefectId从巡检回执表中的到任务id
        RecepitInsp recepitInsp = selectRecepitInspByPoleDefectId(poleDefectId);
        String taskId = recepitInsp.getTaskId();
        // 通过任务id得到该条数据，再得到任务编号
        // 1.封装任务表的查询对象
        Task task = new Task();
        task.setTaskId(taskId);
        // 2.查询并得到编号
        List<Task> tasks = listTask(task);
        if (tasks.size() > 0) {
            return tasks.get(0).getTaskId();
        }
        return null;
    }

    /**
     * 通过poleDefectId从巡检回执表中的到任务id************************************************************可能有问题
     *
     * @param poleDefectId 缺陷记录表的主键id
     * @return
     */
    private RecepitInsp selectRecepitInspByPoleDefectId(int poleDefectId) {
        // 包装查询对象
        RecepitInsp recepitInsp = new RecepitInsp();
        recepitInsp.setPoleDefect(poleDefectId + "");
        List<RecepitInsp> recepitInsps = recepitInspMapper.select(recepitInsp);
        if (recepitInsps.size() > 0) {
            recepitInsp = recepitInsps.get(0);
        }
        return recepitInsp;
    }

    /**
     * 将属于setPoleStatus的查询条件组合成查询对象进行查询
     *
     * @param listRequestDTO 查询业务请求对象
     * @return 查询结果
     */
    private List<PoleDefect> getAllIPending(ListRequestDTO<ConfirmDefectVO> listRequestDTO) {
        // 得到查询请求对象
        ConfirmDefectVO con = listRequestDTO.request;
        // 配置查询对象
        PoleDefect poleDefect = new PoleDefect();
        poleDefect.setStatus("待处理");
        poleDefect.setPoleId(con.getTower_id());
        poleDefect.setFinder(con.getPeople_Finder());
        poleDefect.setPoleDefectLevel(con.getDefect_type());
        // 开启分页
        PageHelper.startPage(listRequestDTO.page, listRequestDTO.pageSize);
        return listPoleDefect(poleDefect);
    }

    private List<Task> listTask(Task task) {
        return taskMapper.listTask(task);
    }

    /**
     * 查询缺陷记录表
     *
     * @param poleDefect 缺陷记录表的实例对象
     * @return 查询结果
     */
    private List<PoleDefect> listPoleDefect(PoleDefect poleDefect) {
        System.out.println(poleDefect);
        return poleDefectMapper.listPoleDefect(poleDefect);
    }

    private Pole selectPole(String poleId) {
        return poleMapper.selectPoleByPoleId(poleId);
    }

}
